import * as sqlite3 from 'sqlite3';
import { promisify } from 'util';
import * as path from 'path';
import * as vscode from 'vscode';

export class CacheManager {
    private db: sqlite3.Database | null = null;
    protected initialized: boolean = false;
    private globalState: vscode.Memento & { setKeysForSync(keys: readonly string[]): void } | null = null;

    constructor() {}

    /**
     * 获取全局状态
     */
    public getGlobalState() {
        return this.globalState;
    }

    /**
     * 检查数据库是否已初始化
     * @returns 数据库初始化状态
     */
    public isInitialized(): boolean {
        return this.initialized;
    }

    /**
     * 初始化数据库连接
     * @param context vscode扩展上下文
     */
    async initialize(context: vscode.ExtensionContext): Promise<void> {
        if (this.initialized) {
            return;
        }

        try {
            // 保存globalState引用
            this.globalState = context.globalState;

            // 获取项目根目录
            const workspaceRoot = vscode.workspace.workspaceFolders?.[0];
            if (!workspaceRoot) {
                throw new Error('未打开任何工作区');
            }

            // 构建数据库文件路径（存储在项目根目录下）
            const dbPath = path.join(workspaceRoot.uri.fsPath, 'cache.dbst3');

            // 创建数据库连接
            this.db = new sqlite3.Database(dbPath, (err) => {
                if (err) {
                    throw new Error(`无法连接到数据库: ${err.message}`);
                }
            });

            // 创建cache表（如果不存在）
            const createTable = promisify(this.db.run.bind(this.db));
            await createTable(`
                CREATE TABLE IF NOT EXISTS cache (
                    local_url TEXT PRIMARY KEY,
                    remote_url TEXT,
                    last_modified INTEGER,
                    created_at INTEGER DEFAULT CURRENT_TIMESTAMP
                )
            `);

            // 设置需要同步的键
            this.globalState.setKeysForSync(['cacheDbPath']);

            // 存储数据库路径到全局状态
            await this.globalState.update('cacheDbPath', dbPath);

            this.initialized = true;
        } catch (error) {
            console.error('初始化数据库失败:', error);
            throw error;
        }
    }

    /**
     * 检查文件是否在缓存中
     * @param filePath 文件路径（相对于工作区）
     */
    async isFileInCache(filePath: string): Promise<boolean> {
        if (!this.db || !this.initialized) {
            console.warn('数据库未初始化，无法检查文件缓存状态');
            return false;
        }

        try {
            // 规范化路径，确保使用正斜杠
            const normalizedPath = filePath.replace(/\\/g, '/');

            const query = 'SELECT COUNT(*) as count FROM cache WHERE local_url = ?';
            const get = promisify(this.db.get).bind(this.db);
            const result = await get(query, [normalizedPath]);

            const isInCache = result && (result as any).count > 0;
            console.log(`文件 ${normalizedPath} ${isInCache ? '在' : '不在'}缓存中`);

            return isInCache;
        } catch (error) {
            console.error('检查文件缓存状态失败:', error);
            if (error instanceof Error) {
                console.error('错误详情:', error.message);
            }
            return false;
        }
    }

    /**
     * 获取所有缓存的Markdown文件路径
     */
    async getCachedMarkdownPaths(): Promise<string[]> {
        if (!this.db || !this.initialized) {
            return [];
        }

        try {
            const query = "SELECT local_url FROM cache WHERE local_url LIKE '%.md'";
            const all = promisify(this.db.all).bind(this.db);
            const rows = await all(query);

            // 假设 rows 应该是一个包含 local_url 属性的对象数组
            return (rows as { local_url: string }[]).map((row) => row.local_url);

        } catch (error) {
            console.error('获取缓存的Markdown文件失败:', error);
            return [];
        }
    }

    /**
     * 关闭数据库连接
     */
    /**
     * 添加文件到缓存
     * @param localPath 本地文件路径（相对于工作区）
     * @param remoteUrl 远程URL（可选）
     */
    async addToCache(localPath: string, remoteUrl?: string): Promise<void> {
        if (!this.db || !this.initialized) {
            throw new Error('数据库未初始化');
        }

        try {
            // 规范化路径，确保使用正斜杠
            const normalizedPath = localPath.replace(/\\/g, '/');

            const query = `
                INSERT OR REPLACE INTO cache (local_url, remote_url, last_modified)
                VALUES (?, ?, ?)
            `;
            const run = promisify(this.db.run).bind(this.db);
            await run(query, [normalizedPath, remoteUrl || null, Date.now()]);

            console.log(`文件 ${normalizedPath} 已添加到缓存`);
        } catch (error) {
            console.error('添加文件到缓存失败:', error);
            if (error instanceof Error) {
                console.error('错误详情:', error.message);
            }
            throw error;
        }
    }

    /**
     * 从缓存中移除文件
     * @param localPath 本地文件路径（相对于工作区）
     */
    async removeFromCache(localPath: string): Promise<void> {
        if (!this.db || !this.initialized) {
            throw new Error('数据库未初始化');
        }

        try {
            // 规范化路径，确保使用正斜杠
            const normalizedPath = localPath.replace(/\\/g, '/');

            const query = 'DELETE FROM cache WHERE local_url = ?';
            const run = promisify(this.db.run).bind(this.db);
            await run(query, [normalizedPath]);

            console.log(`文件 ${normalizedPath} 已从缓存中移除`);
        } catch (error) {
            console.error('从缓存中移除文件失败:', error);
            if (error instanceof Error) {
                console.error('错误详情:', error.message);
            }
            throw error;
        }
    }

    dispose(): void {
        if (this.db) {
            this.db.close();
            this.db = null;
            this.initialized = false;
        }
    }
}

// 导出单例实例
export const cacheManager = new CacheManager();